/**
 * Notes: 智能问答服务
 * Date: 2023-10-01 19:40:00 
 */

const BaseProjectService = require('../base_project_service.js');
const VectorService = require('../vector/vector_service.js');
const LLMService = require('./llm_service.js');
const util = require('../../../../framework/utils/util.js');
const timeUtil = require('../../../../framework/utils/time_util.js');
const config = require('../../../../config/config.js');
const ChatModel = require('../../model/chat_model.js');
const UserModel = require('../../model/user_model.js');

class QAService extends BaseProjectService {

    /**
     * 构造函数
     */
    constructor() {
        super();
        this.vectorService = new VectorService();
        this.llmService = new LLMService();
    }

    /**
     * 处理用户问题
     * @param {string} userId - 用户ID
     * @param {string} question - 用户问题
     * @param {string} sessionId - 会话ID（可选）
     */
    async processQuestion(userId, question, sessionId = '') {
        try {
            // 验证参数
            if (!userId || !question) {
                return { success: false, message: '参数不完整' };
            }
            
            // 清理和标准化问题
            const cleanedQuestion = this._cleanQuestion(question);
            if (!cleanedQuestion) {
                return { success: false, message: '问题内容无效' };
            }
            
            // 创建聊天记录
            const chatId = await this._createChatRecord(userId, cleanedQuestion);
            if (!chatId) {
                return { success: false, message: '创建聊天记录失败' };
            }
            
            // 从向量库中搜索相关文档
            const searchResults = await this.vectorService.semanticSearch(cleanedQuestion, 5);
            
            // 生成回答
            let answer;
            if (process.env.USE_MOCK_LLM === 'true') {
                // 使用模拟LLM（用于开发环境或未配置API时）
                answer = await this.llmService.mockGenerateAnswer(cleanedQuestion, searchResults);
            } else {
                // 使用实际LLM
                answer = await this.llmService.generateAnswer(cleanedQuestion, searchResults, sessionId);
            }
            
            // 更新聊天记录
            if (answer.success) {
                await this._updateChatRecord(chatId, answer);
            }
            
            // 返回结果
            return {
                success: true,
                chatId: chatId,
                answer: answer.success ? answer.answer : '抱歉，我无法回答这个问题，请稍后再试。',
                references: answer.documents || []
            };
            
        } catch (error) {
            console.error('处理问题失败:', error);
            return { success: false, message: '服务异常，请稍后再试' };
        }
    }

    /**
     * 获取用户的聊天历史
     * @param {string} userId - 用户ID
     * @param {number} page - 页码
     * @param {number} size - 每页记录数
     */
    async getChatHistory(userId, page = 1, size = 10) {
        try {
            const result = await ChatModel.getList(userId, page, size);
            return { success: true, ...result };
        } catch (error) {
            console.error('获取聊天历史失败:', error);
            return { success: false, message: '获取聊天历史失败' };
        }
    }

    /**
     * 获取聊天详情
     * @param {string} chatId - 聊天ID
     */
    async getChatDetail(chatId) {
        try {
            const chat = await ChatModel.getOne(chatId);
            if (!chat) {
                return { success: false, message: '找不到该聊天记录' };
            }
            
            return { success: true, chat };
        } catch (error) {
            console.error('获取聊天详情失败:', error);
            return { success: false, message: '获取聊天详情失败' };
        }
    }

    /**
     * 清理和标准化问题文本
     * @private
     */
    _cleanQuestion(question) {
        if (!question) return '';
        
        // 去除多余空格、换行等
        let cleaned = question.trim();
        cleaned = cleaned.replace(/\s+/g, ' ');
        
        // 问题长度限制
        if (cleaned.length > 500) {
            cleaned = cleaned.substring(0, 500);
        }
        
        return cleaned;
    }

    /**
     * 创建聊天记录
     * @private
     */
    async _createChatRecord(userId, question) {
        try {
            // 获取用户信息
            const user = await UserModel.getOne(userId);
            
            // 创建记录
            const data = {
                CHAT_USER_ID: userId,
                CHAT_QUESTION: question,
                CHAT_USER_NAME: user ? user.USER_NAME : '访客',
                CHAT_ADD_TIME: timeUtil.time(),
                CHAT_EDIT_TIME: timeUtil.time(),
                CHAT_STATUS: ChatModel.STATUS.PROCESSING // 初始状态为处理中
            };
            
            const chatId = await ChatModel.insert(data);
            return chatId;
        } catch (error) {
            console.error('创建聊天记录失败:', error);
            return null;
        }
    }

    /**
     * 更新聊天记录
     * @private
     */
    async _updateChatRecord(chatId, answer) {
        try {
            // 准备更新数据
            const data = {
                CHAT_ANSWER: answer.answer,
                CHAT_STATUS: ChatModel.STATUS.COMPLETED,
                CHAT_EDIT_TIME: timeUtil.time()
            };
            
            // 如果有相关文档
            if (answer.documents && answer.documents.length > 0) {
                data.CHAT_REF_KNOWLEDGE_IDS = answer.documents.map(doc => doc.id).join(',');
                data.CHAT_REF_KNOWLEDGE_SCORES = answer.documents.map(doc => doc.score.toFixed(4)).join(',');
            }
            
            // 更新记录
            await ChatModel.edit(chatId, data);
            return true;
        } catch (error) {
            console.error('更新聊天记录失败:', error);
            return false;
        }
    }
}

module.exports = QAService; 